]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
dbusServices/extensions: Only allow one dialog at a time
authorFlorian Müllner <fmuellner@gnome.org>
Tue, 26 Oct 2021 17:40:08 +0000 (19:40 +0200)
committerFlorian Müllner <fmuellner@gnome.org>
Tue, 2 Nov 2021 14:39:08 +0000 (15:39 +0100)
Showing multiple preference dialogs at the same time (for instance
by repeated `gnome-extensions prefs` calls) may or may not work as
expected, depending on whether any of the dialogs is modal or not
(read: opened via the Extensions app).

The easiest way to address this is to disallow more than a single
dialog at the time. It's arguably also the more predictable behavior,
and means extensions don't have to deal with inconsistent state
caused by multiple dialogs.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4564

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2013>
(cherry picked from commit b93342f72e871dc8472a9e92b23b45e0e7ded282)

js/dbusServices/extensions/extensionsService.js

index 7fa32fe80888f45d4e0f394138ba068b95edcf66..10743d4cc79d2e7c754cf1e59ad387afec899b57 100644 (file)
@@ -116,30 +116,37 @@ var ExtensionsService = class extends ServiceImplementation {
             if (this._handleError(invocation, error))
                 return;
 
+            if (this._prefsDialog) {
+                this._handleError(invocation,
+                    new Error('Already showing a prefs dialog'));
+                return;
+            }
+
             const [serialized] = res;
             const extension = ExtensionUtils.deserializeExtension(serialized);
 
-            const window = new ExtensionPrefsDialog(extension);
-            window.connect('realize', () => {
+            this._prefsDialog = new ExtensionPrefsDialog(extension);
+            this._prefsDialog.connect('realize', () => {
                 let externalWindow = null;
 
                 if (parentWindow)
                     externalWindow = Shew.ExternalWindow.new_from_handle(parentWindow);
 
                 if (externalWindow)
-                    externalWindow.set_parent_of(window.get_surface());
+                    externalWindow.set_parent_of(this._prefsDialog.get_surface());
             });
 
             if (options.modal)
-                window.modal = options.modal.get_boolean();
+                this._prefsDialog.modal = options.modal.get_boolean();
 
-            window.connect('close-request', () => {
+            this._prefsDialog.connect('close-request', () => {
+                delete this._prefsDialog;
                 this.release();
                 return false;
             });
             this.hold();
 
-            window.show();
+            this._prefsDialog.show();
 
             invocation.return_value(null);
         });